﻿using Microsoft.Web.WebView2.Core;
using System;
using System.IO;
using System.Net;
using System.Web;
using System.Windows.Controls;
using FxSuperCore.Log;
using System.Windows;
using FxWinSuper.Functions;

namespace FxWinSuper.UI.Doc
{
	/// <summary>
	/// MarkDownViewer.xaml 的交互逻辑
	/// </summary>
	public partial class MarkDownViewer : UserControl
	{
		public static readonly DependencyProperty MarkDownPathProperty = DependencyProperty.Register("MarkDownPath", typeof(string), typeof(MarkDownViewer), new PropertyMetadata(default(string)));

		private static readonly string TemplateDirPath = Path.Combine(Environment.CurrentDirectory, "doc", "template");

		private static readonly string TemplateHtmlPath = Path.Combine(TemplateDirPath, "index.html");

		private ILogPrint Logger { get; }

		public string MarkDownPath
		{
			get => (string) GetValue(MarkDownPathProperty);
			set
			{
				SetValue(MarkDownPathProperty, value);
				uiWebView.Reload();
			}
		}

		public event Func<CoreWebView2WebResourceRequestedEventArgs, bool> OnWebResourceRequest;

		public event Action<CoreWebView2WebResourceRequestedEventArgs> OnMappingFailWebResourceRequest;
		public MarkDownViewer()
		{
			InitializeComponent();
			Logger = new PluginLoggerPrinter("MarkDownFileViwer", InternalLog.Instance);
			InitView();
		}

		private async void InitView()
		{
			uiWebView.CoreWebView2InitializationCompleted += (sender, args) =>
			{
				uiWebView.CoreWebView2.Settings.AreDevToolsEnabled = false;
				uiLoadingPanel.Visibility = Visibility.Collapsed;
				uiWebView.Visibility = Visibility.Visible;
			};
			await uiWebView.EnsureCoreWebView2Async();
			uiWebView.Source = new Uri(TemplateHtmlPath);
			uiWebView.CoreWebView2.AddWebResourceRequestedFilter("*", CoreWebView2WebResourceContext.All);
			uiWebView.CoreWebView2.WebResourceRequested += CoreWebView2_WebResourceRequested;
		}

		private void CoreWebView2_WebResourceRequested(object sender, CoreWebView2WebResourceRequestedEventArgs e)
		{
			if (OnWebResourceRequest?.Invoke(e) ?? false)
			{
				return;
			}

			if (!e.Request.Uri.StartsWith("file:"))
			{
				return;
			}
;
			string filepath = Path.GetFullPath(WebUtility.UrlDecode(new Uri(e.Request.Uri).AbsolutePath));
			if (File.Exists(filepath))
			{
				return;
			}

			if (!filepath.StartsWith(TemplateDirPath))
			{
				Logger.Debug($"file[{filepath}] not root from template-path[{TemplateDirPath}], can't mapping.");
				OnMappingFailWebResourceRequest?.Invoke(e);
				return;
			}

			string mimeType = MimeMapping.GetMimeMapping(filepath);
			if (e.Request.Uri.EndsWith("/template.md"))
			{
				FileStream fs = File.OpenRead(MarkDownPath);
				e.Response = uiWebView.CoreWebView2.Environment.CreateWebResourceResponse(fs, 200, "OK", $"Content-Type: {mimeType}");
				return;
			}

			string markdownFileDir = Path.GetDirectoryName(MarkDownPath);
			string relativePath = filepath.Remove(0, TemplateDirPath.Length + 1);
			string newFilepath = Path.Combine(markdownFileDir, relativePath);
			if (File.Exists(newFilepath))
			{
				FileStream fs = File.OpenRead(newFilepath);
				e.Response = uiWebView.CoreWebView2.Environment.CreateWebResourceResponse(fs, 200, "OK", $"Content-Type: {mimeType}");
				return;
			}

			Logger.Debug($"file[{filepath}] not find mapping from markdown filepath[{markdownFileDir}], can't handle");
			OnMappingFailWebResourceRequest?.Invoke(e);
		}
	}
}
